#include <math.h>
#include <stdio.h>

#define PI 3.14159265359
#define SQRT3 1.73205080757

// 定义一个函数来完成完整的SVPWM运算并输出PWM占空比
void SVPWM(float Udc, float theta, float Vd, float Vq, float PWM_period, float *Ta, float *Tb, float *Tc) {
    float Ualpha, Ubeta, Ua, Ub, Uc;
    float T1 = 0, T2 = 0, T0;
    int sector;

    // 1. Park变换：将d-q轴电压转换为α-β轴电压
    Ualpha = Vd * cos(theta) - Vq * sin(theta);
    Ubeta  = Vd * sin(theta) + Vq * cos(theta);

    // 2. Clarke变换：将α-β轴电压转换为三相电压Ua, Ub, Uc
    Ua = Ualpha;
    Ub = (-Ualpha + SQRT3 * Ubeta) / 2.0;
    Uc = (-Ualpha - SQRT3 * Ubeta) / 2.0;

    // 3. 确定电压空间矢量所在的扇区
    if (Ubeta >= 0) {
        if (Ualpha >= 0) {
            if (Ualpha / SQRT3 > Ubeta) sector = 1; // 扇区1
            else sector = 2; // 扇区2
        } else {
            if (-Ualpha / SQRT3 > Ubeta) sector = 3; // 扇区3
            else sector = 4; // 扇区4
        }
    } else {
        if (Ualpha >= 0) {
            if (Ualpha / SQRT3 > -Ubeta) sector = 6; // 扇区6
            else sector = 5; // 扇区5
        } else {
            if (-Ualpha / SQRT3 > -Ubeta) sector = 4; // 扇区4
            else sector = 5; // 扇区5
        }
    }

    // 4. 计算每个基矢量的作用时间（T1, T2）
    float Uref = sqrt(Ualpha * Ualpha + Ubeta * Ubeta); // 计算矢量的模
    float angle = atan2(Ubeta, Ualpha); // 计算矢量的角度

    // 使用直流母线电压Udc进行归一化处理
    float norm_Uref = Uref / Udc;

    switch (sector) {
        case 1:
            T1 = (SQRT3 * sin(PI / 3 - angle)) * norm_Uref * PWM_period;
            T2 = (SQRT3 * sin(angle)) * norm_Uref * PWM_period;
            break;
        case 2:
            T1 = (SQRT3 * sin(2 * PI / 3 - angle)) * norm_Uref * PWM_period;
            T2 = (SQRT3 * sin(angle - PI / 3)) * norm_Uref * PWM_period;
            break;
        case 3:
            T1 = (SQRT3 * sin(4 * PI / 3 - angle)) * norm_Uref * PWM_period;
            T2 = (SQRT3 * sin(angle - 2 * PI / 3)) * norm_Uref * PWM_period;
            break;
        case 4:
            T1 = (SQRT3 * sin(5 * PI / 3 - angle)) * norm_Uref * PWM_period;
            T2 = (SQRT3 * sin(angle - 4 * PI / 3)) * norm_Uref * PWM_period;
            break;
        case 5:
            T1 = (SQRT3 * sin(2 * PI - angle)) * norm_Uref * PWM_period;
            T2 = (SQRT3 * sin(angle - 5 * PI / 3)) * norm_Uref * PWM_period;
            break;
        case 6:
            T1 = (SQRT3 * sin(angle + PI / 3)) * norm_Uref * PWM_period;
            T2 = (SQRT3 * sin(PI / 3 - angle)) * norm_Uref * PWM_period;
            break;
    }

    // 5. 计算零矢量时间T0
    T0 = PWM_period - (T1 + T2);

    // 6. 设置PWM输出（计算三相占空比）
    *Ta = (T1 + T2 + T0 / 2) / PWM_period * 1000; // Ta = T1 + T2 + T0/2
    *Tb = (T2 + T0 / 2) / PWM_period * 1000;       // Tb = T2 + T0/2
    *Tc = (T0 / 2) / PWM_period * 1000;             // Tc = T0/2
}

int main() {
    // 输入直流电压Udc，电角度theta，d-q轴电压Vd, Vq，以及PWM周期
    float Udc = 400.0; // 直流电压
    float theta = PI / 4; // 电角度，单位是弧度
    float Vd = 200.0; // d轴电压
    float Vq = 100.0; // q轴电压
    float PWM_period = 1000.0;

    // PWM占空比输出变量
    float Ta, Tb, Tc;

    // 调用SVPWM函数
    SVPWM(Udc, theta, Vd, Vq, PWM_period, &Ta, &Tb, &Tc);

    // 打印结果
    printf("PWM输出占空比: Ta = %f, Tb = %f, Tc = %f\n", Ta, Tb, Tc);

   system("pause");
    return 0;
}